package com.custom.custapi.handler;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.custom.custapi.mapper.SuperBaseMapper;
import com.custom.custapi.pojo.SuperBaseEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;

import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author zl
 * @version 1.0
 * @description
 * @date 2025/1/1 1:1
 */
@Slf4j
@SuppressWarnings("unchecked")
public class SuperBaseMapperHandler {

    protected ApplicationContext applicationContext;
    protected int defaultBatchSize;

    public SuperBaseMapperHandler(ApplicationContext applicationContext, int defaultBatchSize) {
        this.applicationContext = applicationContext;
        this.defaultBatchSize = defaultBatchSize;
    }

    public <T extends SuperBaseEntity> SuperBaseMapper<T> getMapper(Class<T> boClazz) {
        T bo;
        try {
            bo = boClazz.getDeclaredConstructor().newInstance();
        } catch (NoSuchMethodException | InstantiationException | IllegalAccessException |
                 InvocationTargetException e) {
            throw new RuntimeException("an exception occurs while create BO ", e);
        }
        return getMapper(bo);
    }

    public <T extends SuperBaseEntity> SuperBaseMapper<T> getMapper(T bo) {
        if (bo == null) {
            throw new NullPointerException("BO is empty,please check the parameters");
        }
        String mapperName = bo.getMapperName();
        Class<T> boClass;
        try {
            boClass = (Class<T>) Class.forName(mapperName);
        } catch (ClassNotFoundException e) {
            log.error("dao class not found", e);
            throw new NoSuchBeanDefinitionException("not taken Dao in Service");
        }
        Object baseMapper = applicationContext.getBean(boClass);
        if (baseMapper instanceof SuperBaseMapper) {
            return (SuperBaseMapper<T>) baseMapper;
        } else {
            log.error("dao not found");
            throw new NoSuchBeanDefinitionException("not taken Dao in Service");
        }
    }

    public <T extends SuperBaseEntity> SuperBaseMapper<T> getMapper(Collection<T> dataList) {
        return getMapper(dataList.stream().findFirst().orElseThrow());
    }

    public <T extends SuperBaseEntity> SuperBaseMapper<T> getMapper(Wrapper<T> queryWrapper) {
        return getMapper(queryWrapper.getEntity());
    }

    public Integer countStep(Integer size) {
        return (size + defaultBatchSize - 1) / defaultBatchSize;
    }

    public <T extends SuperBaseEntity> List<List<T>> countStep(Collection<T> dataList) {
        int limit = countStep(dataList.size());
        return Stream.iterate(0, n -> n + 1).limit(limit).parallel().map(a -> dataList.stream().skip((long) a * defaultBatchSize).limit(defaultBatchSize).parallel().collect(Collectors.toList())).collect(Collectors.toList());
    }

}
